<!DOCTYPE html>
<html lang="zh">

<head>
  <meta charset="utf-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <title>
    
    ES6 生成器 - DSRBLOG
    
  </title>
  

  
  
  <link href="atom.xml" rel="alternate" title="DSRBLOG" type="application/atom+xml">
  <link rel="stylesheet" href="asset/css/style.min.css">
  <link rel="stylesheet" href="asset/css/doc.css">
  <script src="asset/app.js"></script>


</head>

<body> <section class="ct-body">
	<div class="container">
		<div class="columns is-variable bd-klmn-columns is-4 is-centered">
			<div class="column is-four-fifths">
				<div class="post-body single-content">
					
					<h1 class="title">
						ES6 生成器
					</h1>


					<div class="media">
						
						
						<div class="media-content">
							<div class="content">
								<p>
									<span class="date">2022/09/21 22:37 下午</span>
									

									

									<br />
									<span class="tran-tags">Tags:</span>&nbsp;
									
									<a class="tag is-link is-light">#ES6新特性</a>
									

								</p>
							</div>
						</div>

					</div>
				</div>
				<article class="markdown-body single-content">
					<p>生成器函数是<code>ES6</code>提供的一种<strong>异步编程</strong>解决方案，语法行为与传统函数完全不同</p>
<ul>
<li>生成器其实是一个特殊的函数</li>
<li>声明与执行均与传统函数存在差异</li>
<li>可以通过<code>for...of</code>进行遍历</li>
</ul>
<h2><a id="%E7%94%9F%E6%88%90%E5%99%A8%E7%9A%84%E5%A3%B0%E6%98%8E%E4%B8%8E%E8%B0%83%E7%94%A8" class="anchor" aria-hidden="true"><span class="octicon octicon-link"></span></a>生成器的声明与调用</h2>
<p><code>yield</code><strong>：</strong> 函数代码的分隔符</p>
<pre class="line-numbers"><code class="language-js">function * gen(){
    console.log(&quot;111&quot;);
    yield 'Test_1';
    console.log(&quot;222&quot;);
    yield 'Test_2';
    console.log(&quot;333&quot;);
}

let iterator = gen();
console.log(iterator); //输出一个迭代器对象

console.log(iterator.next());
//  输出：
//      111
//      {value:Test_1, done:false}

console.log(iterator.next());
//  输出：
//      222
//      {value:Test_2, done:false}

console.log(iterator.next());
//  输出：
//      333
//      {value:undefined, done:true}

for(let v of gen()){
    console.log(v); 
}
//  输出：
//      111
//      Test_1
//      222
//      Test_2
//      333
</code></pre>
<h2><a id="%E7%94%9F%E6%88%90%E5%99%A8%E7%9A%84%E5%8F%82%E6%95%B0%E4%BC%A0%E9%80%92" class="anchor" aria-hidden="true"><span class="octicon octicon-link"></span></a>生成器的参数传递</h2>
<ul>
<li>通过生成器函数可以进行传参</li>
<li>通过<code>next()</code>方法传入的参数将作为上一个<code>yield</code>的返回结果</li>
</ul>
<pre class="line-numbers"><code class="language-js">function* gen(arg){
    console.log(arg);
    let one = yield 111;
    console.log(one);
    let two = yield 222;
    console.log(two);
}

//传参
let iterator = gen('AAA');
console.log(iterator.next()); 
//  输出：
//      AAA
//      {value:111, done:false}

//next方法传入实参
console.log(iterator.next('BBB'));
//  输出：
//      BBB
//      {value:222, done:false}
console.log(iterator.next('CCC'));
//  输出：
//      CCC
//      {value:undefined, done:true}
</code></pre>
<h2><a id="%E7%94%9F%E6%88%90%E5%99%A8%E5%87%BD%E6%95%B0%E5%AE%9E%E4%BE%8B" class="anchor" aria-hidden="true"><span class="octicon octicon-link"></span></a>生成器函数实例</h2>
<p>生成器函数是专门针对异步编程的解决方案，<strong>文件操作、网络操作（Ajax、Request）、数据库操作</strong>都是异步操作</p>
<h3><a id="%E5%AE%9E%E4%BE%8B1" class="anchor" aria-hidden="true"><span class="octicon octicon-link"></span></a>实例1</h3>
<p>实现1s后控制台输出111，2s后输出222，3s后输出333</p>
<h4><a id="%E5%AE%9A%E6%97%B6%E5%99%A8%E5%AE%9E%E7%8E%B0" class="anchor" aria-hidden="true"><span class="octicon octicon-link"></span></a>定时器实现</h4>
<ul>
<li>通过<code>setTimeout()</code>不断嵌套，层层回调，回调地狱</li>
</ul>
<pre class="line-numbers"><code class="language-js">setTimeout(()=&gt;{
    console.log(111);
    
    setTimeout(()=&gt;{
        console.log(222);
        
        setTimeout(()=&gt;{
            console.log(333);
        },3000);
        
    },2000);
    
},1000);
</code></pre>
<h4><a id="%E7%94%9F%E6%88%90%E5%99%A8%E5%AE%9E%E7%8E%B0" class="anchor" aria-hidden="true"><span class="octicon octicon-link"></span></a>生成器实现</h4>
<pre class="line-numbers"><code class="language-js">function one(){
    setTimeout(()=&gt;{
        console.log(111);
        iterator.next();
    },1000);
}

function two(){
    setTimeout(()=&gt;{
        console.log(222);
        iterator.next();
    },2000);
}

function three(){
    setTimeout(()=&gt;{
        console.log(333);
        iterator.next();
    },3000);
}

function* gen(){
    yield one();
    yield two();
    yield three();
}

//调用生成器函数
let iterator = gen();
iterator.next();
</code></pre>
<h3><a id="%E5%AE%9E%E4%BE%8B2" class="anchor" aria-hidden="true"><span class="octicon octicon-link"></span></a>实例2</h3>
<p>模拟获取用户数据 =&gt; 订单数据 =&gt; 商品数据</p>
<pre class="line-numbers"><code class="language-js">function getUsers(){
    setTimeout(()=&gt;{
        let data = '用户数据';
        //调用next方法，并且将数据传入
        iterator.next(data);
    },1000);
}
    
function getOrders(){
    setTimeout(()=&gt;{
        let data = '订单数据';
        iterator.next(data);
    },1000);
 }
    
function getGoods(){
    setTimeout(()=&gt;{
        let data = '商品数据';
        iterator.next(data);
    },1000);
}
    
function* gen(){
    let users = yield getUsers();
    console.log(users);
    let orders = yield getOrders();
    console.log(orders);
    let goods = yield getGoods();
    console.log(goods);
}
    
let iterator = gen();
iterator.next();
</code></pre>

				</article>
				<div class="comments-wrap">
					<div class="share-comments">
						

						

						
					</div>
				</div><!-- end comments wrap -->
			</div>
		</div><!-- end columns -->
	</div><!-- end container -->
</section>  














<script src="asset/prism.js"></script>









</body>

</html>